#include <disp_manager.h>
#include  <stdio.h>
#include <string.h>
#include <freetype2/ft2build.h>
#include <font_manager.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
/*用于管理底层framebuff或者web等显示设备*/
 
static PDispOpr g_DispDevs = NULL;//
/*构造一个链表，用于注册底层lcd，web的结构体*/
static PDispOpr g_DispDefault = NULL;
/*表示被select后最终选择的显示设备*/
static DispBuffer g_tDispBuffer ;
 
static int line_width;//一行的宽度
static int pixel_width;//一个像素的宽度
/********************************************************
* Function name ： DrawTextInRegionCentral
* Description : 居中写字
* Parameter ：要写的名字，要显示区域的PRegion结构体指针，字体的颜色dwColor
* Return ：无
**********************************************************/
void DrawTextInRegionCentral(char *name , PRegion ptRegion , int dwColor)
{
    int n =strlen(name);
    int iFontSize = ptRegion->iWidth/n/2;
    int OriginX , OriginY ;
    FontBitmap tFontBitmap ;
    int err;
    int i = 0;

    if(iFontSize > ptRegion->iHeigh)
    {
        iFontSize = ptRegion->iHeigh ;
    }

    OriginX = ptRegion->iLeftUpX + (ptRegion->iWidth - iFontSize*n)/2;
    OriginY = ptRegion->iLeftUpY + (ptRegion->iHeigh - iFontSize)/2 + iFontSize;

    SetFontSize(iFontSize);

    while(name[i])
    {
        /* get bitmap */
        tFontBitmap.iCurOriginX = OriginX;
        tFontBitmap.iCurOriginY = OriginY;
        err = GetFontBitmap(name[i],&tFontBitmap);
        if(err)
        {
            printf("Get fontbitmap error\n");
            return ;
        }

        /* draw */
        DrawFontBitmap(&tFontBitmap , 0xff0000);


        OriginX = tFontBitmap.iNextOriginX;
        OriginY = tFontBitmap.iNextOriginY;
        i++;

    }
}


/********************************************************
* Function name ： DrawFontBitmap
* Description : 绘制字体的位图
* Parameter ：字体的位图结构体指针PFontBitmap，字体的颜色dwColor
* Return ：无
**********************************************************/

void DrawFontBitmap(PFontBitmap ptFontBitmap , int dwColor)
{
    int  i, j, p, q;
    int x = ptFontBitmap->tRegion.iLeftUpX;
    int y = ptFontBitmap->tRegion.iLeftUpY;
    int  x_max = x + ptFontBitmap->tRegion.iWidth;
    int  y_max = y + ptFontBitmap->tRegion.iHeigh;
    int  width = ptFontBitmap->tRegion.iWidth;
    unsigned char *buffer = ptFontBitmap->pucBuffer;
    //printf("x = %d, y = %d\n", x, y);

    for ( j = y, q = 0; j < y_max; j++, q++ )
    {
        for ( i = x, p = 0; i < x_max; i++, p++ )
        {
            if ( i < 0      || j < 0       ||
                i >= g_tDispBuffer.iXres || j >= g_tDispBuffer.iYres )
            continue;

            //image[j][i] |= bitmap->buffer[q * bitmap->width + p];
            if(buffer[q * width + p])
            {
                PutPixel(i, j,dwColor);
            }
        }
    }    
}
/********************************************************
* Function name ： DrawRegion
* Description : 绘制一块区域
* Parameter ：区域的结构体指针PRegion，区域的颜色dwColor
* Return ：无
**********************************************************/
void DrawRegion(PRegion ptRegion , int dwColor)
{
    int x = ptRegion->iLeftUpX ;
    int y = ptRegion->iLeftUpY ;
    int width = ptRegion->iWidth ;
    int height = ptRegion->iHeigh ;
    int i ,j ;

    for(j = y ; j < y + height ; j++)
    {
        for(i = x ; i < x + width ; i++)
        {
            PutPixel(i , j , dwColor);
        }
    }

}

/********************************************************
* Function name ： RegisterDisplayer
* Description : 把framebuffer中或者其他显示设备的结构体注册进g_DispDevs这个链表中
* Parameter ：要注册进链表的结构体指针PDispOpr
* Return ：无
**********************************************************/
void RegisterDisplayer(PDispOpr ptDisOpr) 
{
    ptDisOpr->ptNext = g_DispDevs;//链表头插入
    g_DispDevs = ptDisOpr;
}
 
/********************************************************
* Function name ： DisPlayInit
* Description : 初始化显示设备
* Parameter 无
* Return ：无
**********************************************************/
void DisPlayInit(void)
{
    extern void FrameBufferInit(void);
    FrameBufferInit();
    //WebInit();
}
 

/********************************************************
* Function name ： SelectDefaultDisplay
* Description : 遍历链表，选择默认的显示设备
* Parameter ：要寻找设备的名字
* Return ：0 --success , other -- fail
**********************************************************/
int SelectDefaultDisplay (char *name)
{
    PDispOpr Ptemp = g_DispDevs;//局部变量储存已经注册的显示设备
    while(Ptemp)
    {/*遍历链表*/
    if(strcmp(name, Ptemp->name) == 0)
    {// 名字相同选择该结构体
        g_DispDefault = Ptemp;
        return 0;
    }
    /*如果名字不相同，进入下一个结构体再判断*/
    Ptemp = Ptemp->ptNext;
    }
    return -1;
}
 

/********************************************************
* Function name ： InitDefaultDisplay
* Description : 默认显示设备初始化并获取framebuffer起始地址
* Parameter 无
* Return ：0 --success , other -- fail
**********************************************************/
int InitDefaultDisplay (void)
{
    int iRet ;
 
    iRet = g_DispDefault->DeviceInit();
    if (iRet)
    {
        printf("DeviceInit err\r\n");
        return -1;
    }
    g_DispDefault->Getbuffer(&g_tDispBuffer);
    if (iRet)
    {
        printf("Getbuffer err\r\n");
        return -1;
    }
    pixel_width = g_tDispBuffer.iBpp/8;
    line_width = g_tDispBuffer.iXres*g_tDispBuffer.iBpp/8;
    return 0;
}


/********************************************************
* Function name ： GetDispBuffer
* Description : 获取显示区域的buffer
* Parameter 无
* Return ：获取到buffer的结构体指针PDispBuffer
**********************************************************/
PDispBuffer GetDispBuffer (void)
{
    return &g_tDispBuffer;
}
 
/********************************************************
* Function name ： PutPixel
* Description : 描点函数
* Parameter 需要绘制的点的x，y坐标，需要绘制的颜色
* Return ：0 --success , other -- fail
**********************************************************/
int PutPixel (int x, int y, unsigned int dwColor)
{
    unsigned char *pen_8 = (unsigned char *)(g_tDispBuffer.buf+y*line_width+x*pixel_width);
	unsigned short *pen_16;	
	unsigned int *pen_32;	
 
	unsigned int red, green, blue;	
 
	pen_16 = (unsigned short *)pen_8;
	pen_32 = (unsigned int *)pen_8;
 
	switch (g_tDispBuffer.iBpp)
	{
		case 8:
		{
			*pen_8 = dwColor;
			break;
		}
		case 16:
		{
			/* 565 */
			red   = (dwColor >> 16) & 0xff;
			green = (dwColor >> 8) & 0xff;
			blue  = (dwColor >> 0) & 0xff;
			dwColor = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
			*pen_16 = dwColor;
			break;
		}
		case 32:
		{
			*pen_32 = dwColor;
			break;
		}
		default:
		{
			printf("can't surport %dbpp\n", g_tDispBuffer.iBpp);
			break;
            return -1;
		}
        
	}
        return 0;
}

/********************************************************
* Function name ： FlashDisplayRegion
* Description : 把绘制好的buffer刷到显示设备上
* Parameter ： 显示区域的结构体指针PRegion ， 绘制好的buffer的结构体指针PDispBuffer
* Return ：0 --success , other -- fail
**********************************************************/
int FlashDisplayRegion(PRegion ptRegion , PDispBuffer ptDisBuff)
{
    return g_DispDefault->FlashRegion(ptRegion , ptDisBuff);
}